﻿/**
 * 字符串编码转换
 *
 * @file Unicode.hpp
 * @date 2011-11-30
 * 
 */


#pragma once

#ifndef _UNICODE_HPP
#define _UNICODE_HPP


#if defined(WIN32) || defined(_WIN32)
#	ifndef WIN32_LEAN_AND_MEAN
#		define WIN32_LEAN_AND_MEAN
#	endif
#	include <windows.h>
#endif

#include "../platform_config.h"
#include "dynamic_array.hpp"

/// @addtogroup helpers_text
/// @{
namespace helpers {

	namespace text {

		enum CodePage {
			UNKNOWN = 0
			, ASCII = 20127
			, BIG5 = 950
			, EUC_CN = 51936
			, EUC_JP = 51932
			, EUC_KR = 51949
			, GB2312 = 20936
			, GB18030 = 54936
			, GBK = 936
			, HZ_GB2312 = 52936
			, KOI8_R = 20866
			, KOI8_U = 21866
			, ISO_8859_1 = 28591
			, ISO_8859_2 = 28592
			, ISO_8859_3 = 28593
			, ISO_8859_4 = 28594
			, ISO_8859_5 = 28595
			, ISO_8859_6 = 28596
			, ISO_8859_7 = 28597
			, ISO_8859_8 = 28598
			, ISO_8859_9 = 28599
			, SHIFT_JIS = 932
			, US_ASCII = ASCII
			, UTF7 = 65000
			, UTF8 = 65001
			, UTF16LE = 1200
			, UTF16BE = 1201
			, UTF16 = UTF16LE
			, UTF32LE = 12000
			, UTF32BE = 12001
			, UTF32 = UTF32LE
		}; // enum CodePage;

#ifdef WINDOWS_PLATFORM
		/**
		 * 编码转换器
		 */
		class Unicode
		{
		public:
			static ByteArray fromUtf16(const wchar_t *utf16, const CodePage& e)
			{
				size_t len = fromUtf16Length(utf16, e);
				if (len == 0)
					return ByteArray(0);
				ByteArray ba(len * sizeof(char));
				WideCharToMultiByte(e, 0, utf16, -1, static_cast<char*>(ba), len, NULL, NULL);
				return ba;
			}

			static ByteArray fromUtf16(const std::wstring& utf16, const CodePage& e)
			{
				return fromUtf16(utf16.c_str(), e);
			}

			static size_t fromUtf16Length(const wchar_t *utf16, const CodePage& e)
			{
				return WideCharToMultiByte(e, 0, utf16, -1, NULL, 0, NULL, NULL);
			}

			static ByteArray utf8ToAnsi(const char* utf8)
			{
				ByteArray utf16;
				toUtf16(utf8, UTF8).swap(utf16);

				ByteArray ansi;
				fromUtf16(utf16, UNKNOWN).swap(ansi);
				return ansi;
			}


			static ByteArray ansiToUtf8(const char* ansi)
			{
				ByteArray utf16;
				toUtf16(ansi, UNKNOWN).swap(utf16);

				ByteArray utf8;
				fromUtf16(utf16, UTF8).swap(utf8);
				return utf8;
			}


			/**
			* 多字节字符串转宽字节字符号串;
			* @param [in] s 多字节字符串;
			* @param [in] e 多字节字符串编码;
			* @return 转换后的字节数组;
			*/
			static ByteArray toUtf16(const char* s, const CodePage& e)
			{
				size_t len = toUtf16Length(s, e);
				if (len == 0)
					return ByteArray(0);
				ByteArray ba(len * sizeof(wchar_t));
				MultiByteToWideChar(static_cast<UINT>(e), 0, s, -1, static_cast<wchar_t *>(ba), len);
				return ba;
			}

			/**
			* 多字节字符串转宽字节字符号串;
			* @param [in] s 多字节字符串;
			* @param [in] e 多字节字符串编码;
			* @return 转换后的字节数组;
			*/
			static ByteArray toUtf16(const std::string& s, const CodePage& e)
			{
				return toUtf16(s.c_str(), e);
			}

			/**
			* 获取多字节字符串转宽字节字符号串长度;
			* @param [in] s 多字节字符串;
			* @param [in] e 多字节字符串编码;
			* @return 宽字节字符号串长度;
			*/
			static size_t toUtf16Length(const char *s, const CodePage& e)
			{
				return MultiByteToWideChar(e, 0, s, -1, NULL, 0);
			}
		};
#else
	 class Unicode
		{
		public:
			static ByteArray fromUtf16(const wchar_t *utf16, const CodePage& e)
			{
				ByteArray ba;
				return ba;
			}

			static ByteArray fromUtf16(const std::wstring& utf16, const CodePage& e)
			{
				ByteArray ba;
				return ba;
			}

			static size_t fromUtf16Length(const wchar_t *utf16, const CodePage& e)
			{
				return 1;
			}

			static ByteArray utf8ToAnsi(const char* utf8)
			{
				ByteArray ba;
				return ba;
			}


			static ByteArray ansiToUtf8(const char* ansi)
			{
				ByteArray ba;
				return ba;
			}


			static ByteArray toUtf16(const char* s, const CodePage& e)
			{
				ByteArray ba;
				return ba;
			}


			static ByteArray toUtf16(const std::string& s, const CodePage& e)
			{
				ByteArray ba;
				return ba;
			}


			static size_t toUtf16Length(const char *s, const CodePage& e)
			{
				return 1;
			}
		};
#endif // WIN32

	} // namespace text

} // namespace helpers
/// @}

#endif



